/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.service.grant.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.context.GlobalExtendedContext;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.MetaService;
import com.je.common.base.util.DateUtils;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.rpc.func.MetaFuncRpcService;
import com.je.rbac.exception.PermissionException;
import com.je.rbac.service.grant.RbacGrantService;
import com.je.rbac.service.permission.GrantMethodEnum;
import com.je.rbac.service.permission.GrantTypeEnum;
import com.je.rbac.service.permission.template.PcFuncBaseService;
import com.je.rbac.service.permission.template.PcFuncButtonService;
import com.je.rbac.service.permission.template.PcMenuDataService;
import com.je.rbac.service.permission.template.PcSubFuncRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class RbacGrantServiceImpl implements RbacGrantService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private PcMenuDataService pcMenuDataService;
    @Autowired
    private PcFuncBaseService pcFuncBaseService;
    @Autowired
    private PcFuncButtonService pcFuncButtonService;
    @Autowired
    private PcSubFuncRelationService pcSubFuncRelationService;
    @Autowired
    private MetaResourceService metaResourceService;
    @Autowired
    private MetaFuncRpcService metaFuncRpcService;

    private void wrapperThreeMemberMenus(ConditionsWrapper wrapper) {
        List<String> menuIdList = new ArrayList<>();
        List<DynaBean> beanList = metaService.select("JE_RBAC_RESOURCESCOPE", ConditionsWrapper.builder().orderByDesc("SY_CREATETIME"));
        if (beanList != null && !beanList.isEmpty()) {
            for (int i = 0; i < beanList.size(); i++) {
                if (!Strings.isNullOrEmpty(beanList.get(i).getStr("RESOURCESCOPE_MENU_ID"))) {
                    menuIdList.addAll(Splitter.on(",").splitToList(beanList.get(i).getStr("RESOURCESCOPE_MENU_ID")));
                }
            }
            wrapper.notIn("JE_CORE_MENU_ID", menuIdList);
        }
    }

    @Override
    public List<Map<String, Object>> loadTopMenus(GrantMethodEnum grantMethod, String ids, boolean develop) {
        List<Map<String, Object>> topMenuMapResut;
        ConditionsWrapper menuWrapper = ConditionsWrapper.builder().table("JE_CORE_MENU");
        if (develop) {
            menuWrapper.eq("SY_PARENT", "ROOT").orderByAsc("SY_TREEORDERINDEX");
            topMenuMapResut = metaService.selectSql(menuWrapper);
        } else {
            List<Map<String, Object>> productList = metaResourceService.selectMapByNativeQuery(NativeQuery.build().tableCode("JE_PRODUCT_MANAGE").eq("PRODUCT_TYPE", "1"));
            List<Map<String, Object>> maps = metaResourceService.selectMapByNativeQuery(NativeQuery.build().tableCode("JE_PRODUCT_MANAGE").ne("MANAGE_KFYWSQ_ID", "").notNull("MANAGE_KFYWSQ_ID"));

            List<String> productIdList = new ArrayList<>();
            if (productList == null && maps == null) {
                return new ArrayList<>();
            }
            productList.forEach(each -> {
                productIdList.add(each.get("JE_PRODUCT_MANAGE_ID").toString());
            });
            List<String> menuIdList = new ArrayList<>();
            for (Map<String, Object> map : maps) {
                String menuIds = map.get("MANAGE_KFYWSQ_ID").toString();
                for (String menuId : menuIds.split(",")) {
                    menuIdList.add(menuId);
                }
            }

            menuWrapper.eq("SY_PARENT", "ROOT").in("SY_PRODUCT_ID", productIdList).or().in("JE_CORE_MENU_ID", menuIdList);
            if ("1".equals(GlobalExtendedContext.getContextKey("switch"))) {
                wrapperThreeMemberMenus(menuWrapper);
            }
            menuWrapper.orderByAsc("SY_TREEORDERINDEX");
            topMenuMapResut = metaService.selectSql(menuWrapper);
        }

        return topMenuMapResut;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void importFuncs(String strData) {
        JSONArray funcArray = JSON.parseArray(strData);
        DynaBean funcBean;
        for (int i = 0; i < funcArray.size(); i++) {
            funcBean = new DynaBean("JE_RBAC_IMPORTFUNC", false);
            funcBean.set("IMPORTFUNC_FUNCINFO_ID", funcArray.getJSONObject(i).getString("id"));
            funcBean.set("IMPORTFUNC_FUNCINFO_CODE", funcArray.getJSONObject(i).getString("code"));
            funcBean.set("IMPORTFUNC_FUNCINFO_NAME", funcArray.getJSONObject(i).getString("name"));
            funcBean.set("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
            metaService.insert(funcBean);
        }
    }

    private String getFuncCode(DynaBean funcBean) {
        if (funcBean == null) {
            return null;
        }
        return funcBean.getStr("FUNCINFO_FUNCCODE");
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void removeFuncs(String type, String targetIds, String funcIds) {
        List<String> targetIdList = Splitter.on(",").splitToList(targetIds);
        List<String> idList = Splitter.on(",").splitToList(funcIds);
        List<DynaBean> importedFuncList = metaService.select("JE_RBAC_IMPORTFUNC", ConditionsWrapper.builder().in("IMPORTFUNC_FUNCINFO_ID", idList));
        List<String> funcCodeList = new ArrayList<>();
        for (int i = 0; importedFuncList != null && !importedFuncList.isEmpty() && i < importedFuncList.size(); i++) {
            funcCodeList.add(importedFuncList.get(i).getStr("IMPORTFUNC_FUNCINFO_CODE"));
        }

        Map<String, List<DynaBean>> funcResult = metaFuncRpcService.findPermedFuncsAndChildFuncsWithButtonsByFuncIds(idList);
        //功能
        List<DynaBean> mainFuncList = funcResult.get("main");
        //子功能
        List<DynaBean> childFuncRelationList = funcResult.get("child");
        //按钮
        List<DynaBean> funcButtonList = funcResult.get("button") == null ? new ArrayList<>() : funcResult.get("button");
        List<String> permCodeList = new ArrayList<>();

        //主功能
        for (DynaBean eachMainFuncBean : mainFuncList) {
            permCodeList.add(pcFuncBaseService.formatPcFuncShowTemplate(eachMainFuncBean.getStr("FUNCINFO_FUNCCODE")));
            permCodeList.add(pcFuncBaseService.formatPcFuncUpdateTemplate(eachMainFuncBean.getStr("FUNCINFO_FUNCCODE")));
            permCodeList.add(pcFuncBaseService.formatPcFuncDeleteTemplate(eachMainFuncBean.getStr("FUNCINFO_FUNCCODE")));
            permCodeList.add(pcFuncBaseService.formatPcFuncConfigTemplate(eachMainFuncBean.getStr("FUNCINFO_FUNCCODE")));
            for (DynaBean eachButton : funcButtonList) {
                if (eachMainFuncBean.getStr("JE_CORE_FUNCINFO_ID").equals(eachButton.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                    permCodeList.add(pcFuncButtonService.formatPcFuncButtonShowTemplate(eachMainFuncBean.getStr("FUNCINFO_FUNCCODE"), eachButton.getStr("RESOURCEBUTTON_CODE")));
                    permCodeList.add(pcFuncButtonService.formatPcFuncButtonUpdateTemplate(eachMainFuncBean.getStr("FUNCINFO_FUNCCODE"), eachButton.getStr("RESOURCEBUTTON_CODE")));
                    permCodeList.add(pcFuncButtonService.formatPcFuncButtonDeleteTemplate(eachMainFuncBean.getStr("FUNCINFO_FUNCCODE"), eachButton.getStr("RESOURCEBUTTON_CODE")));
                }
            }
        }

        //子功能
        if (childFuncRelationList != null && !childFuncRelationList.isEmpty()) {
            Map<String, DynaBean> childParentFuncInfoMap = metaFuncRpcService.findSubFuncParentFuncInfos(childFuncRelationList.stream().map(each -> each.getStr("JE_CORE_FUNCRELATION_ID")).collect(Collectors.toList()));
            for (DynaBean eachChildFuncRelation : childFuncRelationList) {
                if ("func".equals(eachChildFuncRelation.getStr("FUNCRELATION_RELYONTYPE"))) {
                    permCodeList.add(pcFuncBaseService.formatPcFuncShowTemplate(eachChildFuncRelation.getStr("FUNCRELATION_CODE")));
                    permCodeList.add(pcFuncBaseService.formatPcFuncUpdateTemplate(eachChildFuncRelation.getStr("FUNCRELATION_CODE")));
                    permCodeList.add(pcFuncBaseService.formatPcFuncDeleteTemplate(eachChildFuncRelation.getStr("FUNCRELATION_CODE")));
                    permCodeList.add(pcFuncBaseService.formatPcFuncConfigTemplate(eachChildFuncRelation.getStr("FUNCRELATION_CODE")));
                }
                permCodeList.add(pcSubFuncRelationService.formatPcSubFuncRelationShowTemplate(getFuncCode(childParentFuncInfoMap.get(eachChildFuncRelation.getStr("JE_CORE_FUNCRELATION_ID"))), eachChildFuncRelation.getStr("FUNCINFO_FUNCCODE")));
                permCodeList.add(pcSubFuncRelationService.formatPcSubFuncRelationUpdateTemplate(getFuncCode(childParentFuncInfoMap.get(eachChildFuncRelation.getStr("JE_CORE_FUNCRELATION_ID"))), eachChildFuncRelation.getStr("FUNCINFO_FUNCCODE")));
                permCodeList.add(pcSubFuncRelationService.formatPcSubFuncRelationDeleteTemplate(getFuncCode(childParentFuncInfoMap.get(eachChildFuncRelation.getStr("JE_CORE_FUNCRELATION_ID"))), eachChildFuncRelation.getStr("FUNCINFO_FUNCCODE")));
                for (DynaBean eachButton : funcButtonList) {
                    if (eachChildFuncRelation.getStr("FUNCRELATION_FUNCID").equals(eachButton.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                        permCodeList.add(pcFuncButtonService.formatPcFuncButtonShowTemplate(eachChildFuncRelation.getStr("FUNCRELATION_CODE"), eachButton.getStr("RESOURCEBUTTON_CODE")));
                        permCodeList.add(pcFuncButtonService.formatPcFuncButtonUpdateTemplate(eachChildFuncRelation.getStr("FUNCRELATION_CODE"), eachButton.getStr("RESOURCEBUTTON_CODE")));
                        permCodeList.add(pcFuncButtonService.formatPcFuncButtonDeleteTemplate(eachChildFuncRelation.getStr("FUNCRELATION_CODE"), eachButton.getStr("RESOURCEBUTTON_CODE")));
                    }
                }
            }
        }

        if (!permCodeList.isEmpty()) {
            List<DynaBean> permBeanList = metaService.select("JE_RBAC_PERM", ConditionsWrapper.builder().in("PERM_CODE", permCodeList));
            List<String> permIdList = permBeanList.stream().map(each -> each.getStr("JE_RBAC_PERM_ID")).collect(Collectors.toList());
            //角色权限
            metaService.delete("JE_RBAC_ROLEPERM", ConditionsWrapper.builder().in("JE_RBAC_PERM_ID", permIdList).eq("ROLEPERM_GRANTTYPE_CODE", GrantTypeEnum.FUNC.name()));
            //部门权限
            metaService.delete("JE_RBAC_DEPTPERM", ConditionsWrapper.builder().in("JE_RBAC_PERM_ID", permIdList).eq("DEPTPERM_GRANTTYPE_CODE", GrantTypeEnum.FUNC.name()));
            //机构权限
            metaService.delete("JE_RBAC_ORGPERM", ConditionsWrapper.builder().in("JE_RBAC_PERM_ID", permIdList).eq("ORGPERM_GRANTTYPE_CODE", GrantTypeEnum.FUNC.name()));
            //权限组权限
            metaService.delete("JE_RBAC_PERMGROUPPERM", ConditionsWrapper.builder().in("JE_RBAC_PERM_ID", permIdList).eq("PERMGROUPPERM_GRANTTYPE_CODE", GrantTypeEnum.FUNC.name()));
        }

        metaService.delete("JE_RBAC_IMPORTFUNC", ConditionsWrapper.builder().in("IMPORTFUNC_FUNCINFO_ID", idList));
    }

    @Override
    public List<Map<String, Object>> loadImportFuncs() {
        return metaService.selectSql("SELECT * FROM JE_RBAC_IMPORTFUNC");
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void selfControlPerm(GrantTypeEnum grantType, GrantMethodEnum grantMethod, String id, String strData) throws PermissionException {
        JSONArray operationObjArray = JSON.parseArray(strData);
        Map<String, Boolean> funcCodeMap = new HashMap<>();
        Map<String, Boolean> menuIdMap = new HashMap<>();
        Map<String, Map<String, Boolean>> buttonCodeMap = new HashMap<>();
        Map<String, Boolean> tempButtonMap;
        for (int i = 0; i < operationObjArray.size(); i++) {
            //功能
            if ("MT".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))
                    || "subFunc".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))) {
                funcCodeMap.put(operationObjArray.getJSONObject(i).getString("nodeInfo"),
                        operationObjArray.getJSONObject(i).getBooleanValue("checked"));
                continue;
            }

            //菜单
            if (!"MT".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))
                    && !"subFunc".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))
                    && !"button".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))) {
                menuIdMap.put(operationObjArray.getJSONObject(i).getString("id"),
                        operationObjArray.getJSONObject(i).getBooleanValue("checked"));
                continue;
            }

            //按钮
            if ("button".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))) {
                if (buttonCodeMap.containsKey(operationObjArray.getJSONObject(i).getString("funcCode"))) {
                    tempButtonMap = buttonCodeMap.get(operationObjArray.getJSONObject(i).getString("funcCode"));
                } else {
                    tempButtonMap = new HashMap<>();
                    buttonCodeMap.put(operationObjArray.getJSONObject(i).getString("funcCode"), tempButtonMap);
                }
                tempButtonMap.put(operationObjArray.getJSONObject(i).getString("nodeInfo"),
                        operationObjArray.getJSONObject(i).getBooleanValue("checked"));
            }
        }

        //权限集合
        Map<DynaBean, Boolean> permissionMap = new HashMap<>();
        for (Map.Entry<String, Boolean> eachEntry : funcCodeMap.entrySet()) {
            permissionMap.put(pcFuncBaseService.writePcFuncShowPermission(eachEntry.getKey(), true), eachEntry.getValue());
        }

        for (Map.Entry<String, Boolean> eachEntry : menuIdMap.entrySet()) {
            permissionMap.put(pcMenuDataService.writeMenuDataShowTemplate(eachEntry.getKey(), true), eachEntry.getValue());
        }

        for (Map.Entry<String, Map<String, Boolean>> eachFuncEntry : buttonCodeMap.entrySet()) {
            for (Map.Entry<String, Boolean> eachButtonEntry : eachFuncEntry.getValue().entrySet()) {
                permissionMap.put(pcFuncButtonService.writePcFuncButtonShowPermission(eachFuncEntry.getKey(), eachButtonEntry.getKey(), true), eachButtonEntry.getValue());
            }
        }

        if (GrantMethodEnum.ROLE.equals(grantMethod)) {
            updateSelfControlByRole(id, grantType, grantMethod, permissionMap);
        } else if (GrantMethodEnum.DEPARTMENT.equals(grantMethod)) {
            updateSelfControlByDepartment(id, grantType, grantMethod, permissionMap);
        } else {
            throw new PermissionException(String.format("不支持类型【%s】权限自控操作！", grantMethod.name()));
        }

    }

    private void updateSelfControlByRole(String roleId, GrantTypeEnum grantType, GrantMethodEnum grantMethod, Map<DynaBean, Boolean> permissionMap) {
        List<String> permCodeList = new ArrayList<>();
        for (DynaBean eachBean : permissionMap.keySet()) {
            permCodeList.add(eachBean.getStr("PERM_CODE"));
        }
        List<DynaBean> existPermissionBeanList = metaService.select("JE_RBAC_VROLEPERM", ConditionsWrapper.builder()
                .eq("ROLEPERM_TYPE_CODE", grantMethod.name())
                .eq("ROLEPERM_GRANTTYPE_CODE", grantType.name())
                .eq("JE_RBAC_ROLE_ID", roleId)
                .in("PERM_CODE", permCodeList));
        List<String> exitsRolePermissionCodeList = new ArrayList<>();
        for (DynaBean eachBean : existPermissionBeanList) {
            exitsRolePermissionCodeList.add(eachBean.getStr("PERM_CODE"));
            for (Map.Entry<DynaBean, Boolean> eachEntry : permissionMap.entrySet()) {
                if (eachEntry.getKey().getStr("PERM_CODE").equals(eachBean.getStr("PERM_CODE"))) {
                    metaService.executeSql("UPDATE JE_RBAC_ROLEPERM SET ROLEPERM_EXCLUDE_CODE = {0},ROLEPERM_EXCLUDE_NAME = {1},ROLEPERM_NOT_CHECKED = {2} WHERE JE_RBAC_ROLEPERM_ID = {3} ",
                            "1", "是", eachEntry.getValue() ? "0" : "1", eachBean.getStr("JE_RBAC_ROLEPERM_ID"));
                }
            }

        }

        DynaBean eachBean;
        for (Map.Entry<DynaBean, Boolean> eachEntry : permissionMap.entrySet()) {
            if (exitsRolePermissionCodeList != null && !exitsRolePermissionCodeList.isEmpty() && exitsRolePermissionCodeList.contains(eachEntry.getKey().getStr("PERM_CODE"))) {
                continue;
            }
            eachBean = new DynaBean("JE_RBAC_ROLEPERM", false);
            eachBean.set("JE_RBAC_ROLE_ID", roleId);
            eachBean.set("JE_RBAC_PERM_ID", eachEntry.getKey().getStr("JE_RBAC_PERM_ID"));
            eachBean.set("ROLEPERM_EXCLUDE_CODE", "1");
            eachBean.set("ROLEPERM_EXCLUDE_NAME", "是");
            eachBean.set("ROLEPERM_TYPE_CODE", GrantMethodEnum.ROLE.name());
            eachBean.set("ROLEPERM_TYPE_NAME", GrantMethodEnum.ROLE.getDesc());
            eachBean.set("ROLEPERM_GRANTTYPE_CODE", grantType.name());
            eachBean.set("ROLEPERM_GRANTTYPE_NAME", grantType.getDesc());
            eachBean.set("ROLEPERM_NOT_CHECKED", eachEntry.getValue() ? "0" : "1");
            commonService.buildModelCreateInfo(eachBean);
            metaService.insert(eachBean);
        }

    }

    private void updateSelfControlByDepartment(String deptId, GrantTypeEnum grantType, GrantMethodEnum grantMethod, Map<DynaBean, Boolean> permissionMap) {
        List<String> permCodeList = new ArrayList<>();
        for (DynaBean eachBean : permissionMap.keySet()) {
            permCodeList.add(eachBean.getStr("PERM_CODE"));
        }
        List<DynaBean> existPermissionBeanList = metaService.select("JE_RBAC_VDEPTPERM", ConditionsWrapper.builder()
                .eq("DEPTPERM_TYPE_CODE", grantMethod.name())
                .eq("DEPTPERM_GRANTTYPE_CODE", grantType.name())
                .eq("JE_RBAC_DEPARTMENT_ID", deptId)
                .in("PERM_CODE", permCodeList));
        List<String> exitsRolePermissionCodeList = new ArrayList<>();
        for (DynaBean eachBean : existPermissionBeanList) {
            exitsRolePermissionCodeList.add(eachBean.getStr("PERM_CODE"));
            for (Map.Entry<DynaBean, Boolean> eachEntry : permissionMap.entrySet()) {
                if (eachEntry.getKey().getStr("PERM_CODE").equals(eachBean.getStr("PERM_CODE"))) {
                    metaService.executeSql("UPDATE JE_RBAC_DEPTPERM SET DEPTPERM_EXCLUDE_CODE = {0},DEPTPERM_EXCLUDE_NAME = {1},DEPTPERM_NOT_CHECKED = {2} WHERE JE_RBAC_DEPTPERM_ID = {3} ",
                            "1", "是", eachEntry.getValue() ? "0" : "1", eachBean.getStr("JE_RBAC_DEPTPERM_ID"));
                }
            }
        }

        DynaBean eachBean;
        for (Map.Entry<DynaBean, Boolean> eachEntry : permissionMap.entrySet()) {
            if (exitsRolePermissionCodeList.contains(eachEntry.getKey().getStr("PERM_CODE"))) {
                continue;
            }
            eachBean = new DynaBean("JE_RBAC_ROLEPERM", false);
            eachBean.set("JE_RBAC_DEPTPERM_ID", deptId);
            eachBean.set("JE_RBAC_PERM_ID", eachEntry.getKey().getStr("JE_RBAC_PERM_ID"));
            eachBean.set("DEPTPERM_EXCLUDE_CODE", "1");
            eachBean.set("DEPTPERM_EXCLUDE_NAME", "是");
            eachBean.set("DEPTPERM_TYPE_CODE", GrantMethodEnum.DEPARTMENT.name());
            eachBean.set("DEPTPERM_TYPE_NAME", GrantMethodEnum.DEPARTMENT.getDesc());
            eachBean.set("DEPTPERM_GRANTTYPE_CODE", grantType.name());
            eachBean.set("DEPTPERM_GRANTTYPE_NAME", grantType.getDesc());
            eachBean.set("DEPTPERM_NOT_CHECKED", eachEntry.getValue() ? "0" : "1");
            commonService.buildModelCreateInfo(eachBean);
            metaService.insert(eachBean);
        }

    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void cancelSelfControlPerm(GrantTypeEnum grantType, GrantMethodEnum grantMethod, String id, String strData) throws PermissionException {
        JSONArray operationObjArray = JSON.parseArray(strData);
        Map<String, Boolean> funcCodeMap = new HashMap<>();
        Map<String, Boolean> menuIdMap = new HashMap<>();
        Map<String, Map<String, Boolean>> buttonCodeMap = new HashMap<>();
        Map<String, Boolean> tempButtonMap;
        for (int i = 0; i < operationObjArray.size(); i++) {
            //功能
            if ("MT".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))
                    || "subFunc".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))) {
                funcCodeMap.put(operationObjArray.getJSONObject(i).getString("nodeInfo"),
                        operationObjArray.getJSONObject(i).getBooleanValue("checked"));
                continue;
            }

            //菜单
            if (!"MT".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))
                    && !"subFunc".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))
                    && !"button".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))) {
                menuIdMap.put(operationObjArray.getJSONObject(i).getString("id"),
                        operationObjArray.getJSONObject(i).getBooleanValue("checked"));
                continue;
            }

            //按钮
            if ("button".equals(operationObjArray.getJSONObject(i).getString("nodeInfoType"))) {
                if (buttonCodeMap.containsKey(operationObjArray.getJSONObject(i).getString("funcCode"))) {
                    tempButtonMap = buttonCodeMap.get(operationObjArray.getJSONObject(i).getString("funcCode"));
                } else {
                    tempButtonMap = new HashMap<>();
                    buttonCodeMap.put(operationObjArray.getJSONObject(i).getString("funcCode"), tempButtonMap);
                }
                tempButtonMap.put(operationObjArray.getJSONObject(i).getString("nodeInfo"),
                        operationObjArray.getJSONObject(i).getBooleanValue("checked"));
            }
        }

        //权限集合
        List<String> permissionIdList = new ArrayList<>();
        DynaBean eachPermissionBean;
        for (Map.Entry<String, Boolean> eachEntry : funcCodeMap.entrySet()) {
            eachPermissionBean = pcFuncBaseService.writePcFuncShowPermission(eachEntry.getKey(), true);
            permissionIdList.add(eachPermissionBean.getStr("JE_RBAC_PERM_ID"));
        }

        for (Map.Entry<String, Boolean> eachEntry : menuIdMap.entrySet()) {
            eachPermissionBean = pcMenuDataService.writeMenuDataShowTemplate(eachEntry.getKey(), true);
            permissionIdList.add(eachPermissionBean.getStr("JE_RBAC_PERM_ID"));
        }

        for (Map.Entry<String, Map<String, Boolean>> eachFuncEntry : buttonCodeMap.entrySet()) {
            for (Map.Entry<String, Boolean> eachButtonEntry : eachFuncEntry.getValue().entrySet()) {
                eachPermissionBean = pcFuncButtonService.writePcFuncButtonShowPermission(eachFuncEntry.getKey(), eachButtonEntry.getKey(), true);
                permissionIdList.add(eachPermissionBean.getStr("JE_RBAC_PERM_ID"));
            }
        }

        if (GrantMethodEnum.ROLE.equals(grantMethod)) {
            updateRoleCancelSelfControlPerm(id, grantType, grantMethod, permissionIdList);
        } else if (GrantMethodEnum.DEPARTMENT.equals(grantMethod)) {
            updateDeptCancelSelfControlPerm(id, grantType, grantMethod, permissionIdList);
        } else {
            throw new PermissionException(String.format("不支持类型【%s】权限自控操作！", grantMethod.name()));
        }

    }

    private void updateRoleCancelSelfControlPerm(String roleId, GrantTypeEnum grantType, GrantMethodEnum grantMethod, List<String> permissionIdList) {
        List<DynaBean> rolePermBeanList = metaService.select("JE_RBAC_ROLEPERM", ConditionsWrapper.builder()
                .eq("ROLEPERM_TYPE_CODE", grantMethod.name())
                .eq("ROLEPERM_GRANTTYPE_CODE", grantType.name())
                .eq("JE_RBAC_ROLE_ID", roleId)
                .in("JE_RBAC_PERM_ID", permissionIdList));
        for (DynaBean eachBean : rolePermBeanList) {
            if ("1".equals(eachBean.getStr("ROLEPERM_NOT_CHECKED"))) {
                metaService.delete("JE_RBAC_ROLEPERM", ConditionsWrapper.builder().eq("JE_RBAC_ROLEPERM_ID", eachBean.getStr("JE_RBAC_ROLEPERM_ID")));
            } else {
                eachBean.set("ROLEPERM_EXCLUDE_CODE", "0");
                eachBean.set("ROLEPERM_EXCLUDE_NAME", "是");
                metaService.update(eachBean);
            }
        }
    }

    private void updateDeptCancelSelfControlPerm(String deptId, GrantTypeEnum grantType, GrantMethodEnum grantMethod, List<String> permissionIdList) {
        List<DynaBean> rolePermBeanList = metaService.select("JE_RBAC_DEPTPERM", ConditionsWrapper.builder()
                .eq("DEPTPERM_TYPE_CODE", grantMethod.name())
                .eq("DEPTPERM_GRANTTYPE_CODE", grantType.name())
                .eq("JE_RBAC_DEPARTMENT_ID", deptId)
                .in("JE_RBAC_PERM_ID", permissionIdList));
        for (DynaBean eachBean : rolePermBeanList) {
            if ("1".equals(eachBean.getStr("DEPTPERM_NOT_CHECKED"))) {
                metaService.delete("JE_RBAC_DEPTPERM", ConditionsWrapper.builder()
                        .eq("JE_RBAC_DEPTPERM_ID", eachBean.getStr("JE_RBAC_DEPTPERM_ID")));
            } else {
                eachBean.set("DEPTPERM_EXCLUDE_CODE", "0");
                eachBean.set("DEPTPERM_EXCLUDE_NAME", "是");
                metaService.update(eachBean);
            }
        }
    }

}
